package com.suneast.suneaststore.modules.personal.wallet.bankcard;

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.suneast.suneaststore.API;
import com.suneast.suneaststore.R;
import com.suneast.suneaststore.app.AccountManager;
import com.suneast.suneaststore.bean.personal.bank.BankBean;
import com.suneast.suneaststore.modules.personal.wallet.bankcard.event.AddBankCardResult;
import com.suneast.suneaststore.modules.personal.wallet.bankcard.event.GotBankList;
import com.suneast.suneaststore.modules.personal.sign.SignRequestHandler;
import com.suneast.suneaststore.modules.personal.sign.event.CountDownEvent;
import com.suneast.suneaststore.modules.common.Flag;
import com.suneast.suneaststore.modules.personal.sign.event.RequestAutoCodeResult;
import com.suneast.suneaststore.ui.fragments.BaseFragment;
import com.suneast.suneaststore.util.log.LatteLogger;
import com.suneast.suneaststore.util.net.RestClient;
import com.suneast.suneaststore.util.net.callback.IError;
import com.suneast.suneaststore.util.net.callback.IFailure;
import com.suneast.suneaststore.util.net.callback.ISuccess;
import com.suneast.suneaststore.util.regex.RegexUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.BindView;
import butterknife.OnClick;

public class AddBankCardFragment extends BaseFragment {
    @Override
    public int setLayout() {
        return R.layout.fragment_add_bank_card;
    }

    @Override
    public void onBindView(@Nullable Bundle savedInstanceState, @NonNull View rootView) {
        initData();
        initView();
        requestBankList();
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    @BindView(R.id.toolbar)
    Toolbar toolbar;
    @BindView(R.id.et_input_name)
    EditText nameEdit;
    @BindView(R.id.tv_bank_name)
    TextView bankNameTv;
    @BindView(R.id.group_card_type)
    RadioGroup cardTypeRadioGroup;
    @BindView(R.id.et_input_bank_card_number)
    EditText bankCardNumberEdit;
    @BindView(R.id.et_re_input_bank_card_number)
    EditText bankCardNumberConfirmEdit;
    @BindView(R.id.et_input_phone_number)
    EditText phoneNumberEdit;
    @BindView(R.id.et_input_auth_code)
    EditText authCodeEdit;
    @BindView(R.id.btn_check_back_card_no)
    Button checkCardNoBtn;
    @BindView(R.id.btn_get_code)
    Button getCodeBtn;

    private String name;
    private int bankId;
    private int cardType;
    private String cardNumber;
    private String confirmCardNumber;
    private String phoneNumber;
    private String authCode;
    private String[] bankCodes;

    private void initData() {
        name = "";
        bankId = 0;
        cardType = 1;
        cardNumber = "";
        confirmCardNumber = "";
        phoneNumber = "";
        authCode = "";
        bankList = new ArrayList<>();
        bankCodes = getResources().getStringArray(R.array.bank_codes);
        String[] bankNames = getResources().getStringArray(R.array.bank_names);
        for (int i = 0, iLength = bankNames.length; i < iLength; i++) {
            bankList.add(new BankBean(i + 1, bankNames[i]));
        }
    }

    private void initView() {
        toolbar.setNavigationOnClickListener(v -> pop());
        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                EventBus.getDefault().post(new CountDownEvent(Flag.CodeType.ADD_CARD));
            }
        };
        cardTypeRadioGroup.setOnCheckedChangeListener((RadioGroup group, int checkedId) -> {
            switch (checkedId) {
                case R.id.rb_deposit_card: {
                    cardType = 1;
                }
                break;
                case R.id.rb_credit_card: {
                    cardType = 2;
                }
                break;
            }
        });
        nameEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                name = s.toString();
            }
        });
        bankCardNumberEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                cardNumber = s.toString();
                cardNoValid = false;
            }
        });
        bankCardNumberConfirmEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                confirmCardNumber = s.toString();
                cardNoValid = false;
            }
        });
        phoneNumberEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                phoneNumber = s.toString();
            }
        });
        authCodeEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                authCode = s.toString();
            }
        });

    }

    @OnClick({R.id.btn_check_back_card_no, R.id.tv_bank_name, R.id.img_click, R.id.btn_get_code, R.id.btn_add_card})
    public void onViewClick(View view) {
        switch (view.getId()) {
            case R.id.btn_check_back_card_no: {
                if (bankId != 0) {
                    if (cardNumber.equals(confirmCardNumber)) {
                        if (RegexUtil.matchLuhn(cardNumber)) {
                            checkCardNoBtn.setEnabled(false);
                            checkBankNo(cardNumber);
                        } else {
                            Toast.makeText(_mActivity, "暂不支持此种卡", Toast.LENGTH_SHORT).show();
                        }
                    } else {
                        Toast.makeText(_mActivity, "两次输入卡号不一致", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(_mActivity, "请点击选择银行", Toast.LENGTH_SHORT).show();
                }
            }
            break;
            case R.id.btn_get_code: {
                // 请求验证码
                if (RegexUtil.isMobile(phoneNumber)) {
                    getCodeBtn.setEnabled(false);
                    SignRequestHandler.requestAuthCode(phoneNumber, Flag.CodeType.AUTH_CODE);
                } else {
                    Toast.makeText(_mActivity, "请输入正确的手机号码", Toast.LENGTH_SHORT).show();
                }
            }
            break;
            case R.id.img_click:
            case R.id.tv_bank_name: {
                // 显示弹窗 展示银行列表供用户选择
                showBankListDialog();
            }
            break;
            case R.id.btn_add_card: {
                //通过API 请求添加银行卡
                if (checkParams()) {// 检查所有参数的合法性
                    requestAddCard();
                }
            }
            break;
        }
    }

    private void requestAddCard() {
        RestClient.builder()
                .url(API.ADD_BANK_CARD)
                .params("token", AccountManager.getToken())
                .params("realname", name)
                .params("cardnum", cardNumber)
                .params("banktype", cardType)
                .params("bankid", bankId)
                .params("mobile", phoneNumber)
                .params("phoneverify", authCode)
                .success(new ISuccess() {
                    @Override
                    public void onSuccess(String response) {
                        JSONObject rootJObj = JSON.parseObject(response);
                        if (rootJObj != null && rootJObj.getIntValue("code") == 1) {
                            EventBus.getDefault().post(new AddBankCardResult(Flag.Result.SUCCEED));
                        } else {
                            EventBus.getDefault().post(new AddBankCardResult(Flag.Result.FAILURE));
                        }
                    }
                })
                .error(new IError() {
                    @Override
                    public void onError(int code, String msg) {
                        LatteLogger.e("test", "requestAddCard error code = "
                                + code + " msg = " + msg);
                        EventBus.getDefault().post(new AddBankCardResult(Flag.Result.FAILURE));
                    }
                })
                .failure(new IFailure() {
                    @Override
                    public void onFailure() {
                        LatteLogger.e("test", "requestAddCard failure ");
                        EventBus.getDefault().post(new AddBankCardResult(Flag.Result.FAILURE));
                    }
                })
                .build()
                .post();
    }

    private void requestBankList() {
        RestClient.builder()
                .url(API.BANK_LIST)
                .params("token", AccountManager.getToken())
                .success(new ISuccess() {
                    @Override
                    public void onSuccess(String response) {
                        LatteLogger.json("test", response);
                        JSONObject rootJObj = JSON.parseObject(response);
                        if (rootJObj != null && rootJObj.getIntValue("code") == 1) {
                            JSONArray dataArray = rootJObj.getJSONArray("data");
                            if (dataArray != null && dataArray.size() > 0) {
                                ArrayList<BankBean> list = new ArrayList<>();
                                for (int i = 0, iLength = dataArray.size(); i < iLength; i++) {
                                    JSONObject obj = dataArray.getJSONObject(i);
                                    BankBean bean = new BankBean(
                                            obj.getIntValue("id"),
                                            obj.getString("bankname")
                                    );
                                    list.add(bean);
                                }
                                EventBus.getDefault().post(new GotBankList(list));
                            }
                        }
                    }
                })
                .error(new IError() {
                    @Override
                    public void onError(int code, String msg) {

                    }
                })
                .failure(new IFailure() {
                    @Override
                    public void onFailure() {

                    }
                })
                .build()
                .post();
    }

    private boolean cardNoValid = false;

    public void checkBankNo(String number) {
        LatteLogger.e("test", "number = " + number);
        RestClient.builder()
                .url(API.CHECK_BANK_NO)
                .params("cardNo", number)
                .params("cardBinCheck", "true")
                .success(response -> {
                    JSONObject rootObj = JSON.parseObject(response);
                    boolean validated = rootObj.getBooleanValue("validated");
                    if (validated) {
                        String bankCode = rootObj.getString("bank");
                        String cardType = rootObj.getString("cardType");
                        if (bankCode.equals(bankCodes[bankId - 1])) {
                            cardNoValid = cardTypeRadioGroup.getCheckedRadioButtonId()
                                    == R.id.rb_deposit_card ? cardType.equals("DC")
                                    : cardType.equals("CC");
                            if (cardNoValid) {
                                Toast.makeText(_mActivity, "银行卡信息无误", Toast.LENGTH_SHORT).show();
                            } else {
                                Toast.makeText(_mActivity, "卡类型与选择不匹配", Toast.LENGTH_SHORT).show();
                            }
                        } else {
                            Toast.makeText(_mActivity, "所属银行与选择不匹配", Toast.LENGTH_SHORT).show();
                            cardNoValid = false;
                        }
                    } else {
                        Toast.makeText(_mActivity, "卡号错误", Toast.LENGTH_SHORT).show();
                    }
                    checkCardNoBtn.setEnabled(true);
                })
                .error((code, msg) -> {
                    Toast.makeText(_mActivity, "银行卡校验失败", Toast.LENGTH_SHORT).show();
                    checkCardNoBtn.setEnabled(true);

                    LatteLogger.e("error", " checkBankNo error code = " + code + " msg = " + msg);
                })
                .failure(() -> {
                    Toast.makeText(_mActivity, "银行卡校验失败", Toast.LENGTH_SHORT).show();
                    checkCardNoBtn.setEnabled(true);
                    LatteLogger.e("error", " checkBankNo failure ");
                })
                .build()
                .post();
    }

    private List<BankBean> bankList = null;

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onGotBankList(GotBankList gotBankList) {
        bankList = gotBankList.getList();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onAddResult(AddBankCardResult result) {
        if (result.getResult() == Flag.Result.SUCCEED) {
            Toast.makeText(_mActivity, "成功添加银行卡", Toast.LENGTH_SHORT).show();
            pop();
        } else {
            Toast.makeText(_mActivity, "添加银行卡失败", Toast.LENGTH_SHORT).show();
        }
    }

    private int count = 90;
    private TimerTask task;
    private Timer timer;

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onRequestAutoCodeResult(RequestAutoCodeResult event) {
        switch (event.getState()) {
            case Flag.Result.SUCCEED: {
                count = 90;
                timer.schedule(task, 0, 1000);
            }
            break;
            case Flag.Result.FAILURE: {
                getCodeBtn.setEnabled(true);
            }
            break;
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onCountDown(CountDownEvent event) {
        if (event.getType() == Flag.CodeType.ADD_CARD) {
            if (count > 0) {
                getCodeBtn.setText(count + getResources().getString(R.string.afresh_auto_code));
                count--;
            } else {
                task.cancel();
                getCodeBtn.setEnabled(true);
                getCodeBtn.setText(getResources().getString(R.string.get_auth_code));
            }
        }
    }

    private String[] bankNameArray = null;
    private AlertDialog bankListDialog = null;

    private void showBankListDialog() {
        if (bankListDialog == null) {
            bankNameArray = getBankNameArray(bankList);
            AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
            builder.setTitle("选择银行");
            builder.setIcon(R.mipmap.ic_launcher);
            builder.setSingleChoiceItems(bankNameArray, 0, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String str = bankNameArray[which];
                    bankNameTv.setText(str);
                    bankId = bankList.get(which).getBankId();
                    dialog.dismiss();
                }
            });
            bankListDialog = builder.create();
            bankListDialog.setCancelable(true);
        }

        bankListDialog.show();
    }

    private String[] getBankNameArray(List<BankBean> bankList) {
        String[] nameArrays = new String[bankList.size()];
        for (int i = 0, iLength = bankList.size(); i < iLength; i++) {
            nameArrays[i] = bankList.get(i).getBankName();
        }
        return nameArrays;
    }

    private boolean checkParams() {
        if (name.length() == 0) {
            Toast.makeText(_mActivity, "请输入持卡人姓名", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (bankNameTv.getText().equals(getResources().getString(R.string.click_to_select))) {
            Toast.makeText(_mActivity, "请点击选择银行", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (!cardNumber.equals(confirmCardNumber)) {
            Toast.makeText(_mActivity, "两次输入卡号不一致", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (checkCardNoBtn.isEnabled()) {
            if (!cardNoValid) {
                Toast.makeText(_mActivity, "请输入正确的银行卡号,匹配的银行和卡类型", Toast.LENGTH_SHORT).show();
                return false;
            }
        } else {
            Toast.makeText(_mActivity, "正在校验银行卡信息", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (!RegexUtil.isMobile(phoneNumber)) {
            Toast.makeText(_mActivity, "请输入正确的手机号码", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (authCode.length() != 4) {
            Toast.makeText(_mActivity, "请输入正确的验证码", Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

}
